<?php
require_once 'common.php';
require_once 'OaAppModel.php';

/**
 * 应用模型
 * @author xucongbin
 *
 */
class OaOperationLogModel extends OpModel
{
    // 开发环境
    const APP_CONFIG_ENV_TEST = 1; // 联调环境
    const APP_CONFIG_ENV_PRODUCTION = 2; // 正式环境
    protected static $envList = array(
        self::APP_CONFIG_ENV_TEST => "联调环境", 
        self::APP_CONFIG_ENV_PRODUCTION => "正式环境"
    );
    const APP_DEFAULT_NAME = "所有游戏";
    //老网站动作 1 插入  2修改  3撤消
    const OPERATION_ADD = 1;
    const OPERATION_UPDATE = 2;
    const OPERATION_DELETE = 3;
    //权限管理操作 4 分配权限  5 收回权限  6 权限转让  7 分配角色  8 收回角色  9 角色转让  
    const OPERATION_RIGHT_GRANT = 4;
    const OPERATION_RIGHT_REVOKE = 5;
    const OPERATION_RIGHT_TRANSFER = 6;
    const OPERATION_ROLE_GRANT = 7;
    const OPERATION_ROLE_REVOKE = 8;
    const OPERATION_ROLE_TRANSFER = 9;
    //服务选择 10 选择xx服务
    const OPERATION_SERVICE_OPEN = 10;
    //服务器配置 11 新增游戏区  12 新增游戏组  13 新增服务器  14 删除游戏区  15 删除游戏组  
    //16 删除服务器  17 修改游戏区  18 修改游戏组  19 修改服务器  20 修改idc  21 修改状态  22 产品管理员管理
    const OPERATION_AREA_ADD = 11;
    const OPERATION_GROUP_ADD = 12;
    const OPERATION_GS_ADD = 13;
    const OPERATION_AREA_DELETE = 14;
    const OPERATION_GROUP_DELETE = 15;
    const OPERATION_GS_DELETE = 16;
    const OPERATION_AREA_UPDATE = 17;
    const OPERATION_GROUP_UPDATE = 18;
    const OPERATION_GS_UPDATE = 19;
    const OPERATION_IDC_UPDATE = 20;
    const OPERATION_STATUS_UPDATE = 21;
    //服务取消 22 不选xx服务
    const OPERATION_SERVICE_CLOSE = 22;
    //基本信息修改
    const OPERATION_INFO_MODIFY = 23;
    
    //基本信息修改
    const OPERATION_SERVICE_OPEN_FAIL = 24;
    
    //创建商户
    const OPERATION_COMPANY_CREATE = 25;
    const OPERATION_APP_CREATE = 26;
    
    const OPERATION_COPY_CONFIG = 27;
    const OPERATION_AUTHTEST = 28;
    
    protected static $_opList = array(
//        self::OPERATION_ADD => '插入', 
//        self::OPERATION_UPDATE => '修改', 
//        self::OPERATION_DELETE => '删除', 
        self::OPERATION_RIGHT_GRANT => '分配公司角色', 
        self::OPERATION_RIGHT_REVOKE => '收回公司角色 ', 
        self::OPERATION_RIGHT_TRANSFER => '转让公司管理员 ', 
        self::OPERATION_ROLE_GRANT => '分配产品角色 ', 
        self::OPERATION_ROLE_REVOKE => '收回产品角色', 
        self::OPERATION_ROLE_TRANSFER => '更换产品管理员  ', 
        self::OPERATION_SERVICE_OPEN => '开通服务', 
        self::OPERATION_AREA_ADD => '新增游戏区', 
        self::OPERATION_GROUP_ADD => '新增游戏组', 
        self::OPERATION_GS_ADD => '新增服务器', 
        self::OPERATION_AREA_DELETE => '删除游戏区', 
        self::OPERATION_GROUP_DELETE => '删除游戏组', 
        self::OPERATION_GS_DELETE => '删除服务器', 
        self::OPERATION_AREA_UPDATE => '修改游戏区', 
        self::OPERATION_GROUP_UPDATE => '修改游戏组', 
        self::OPERATION_GS_UPDATE => '修改服务器', 
        self::OPERATION_IDC_UPDATE => '修改idc', 
        self::OPERATION_STATUS_UPDATE => '修改状态 ',
        self::OPERATION_SERVICE_CLOSE => '取消服务', 
        self::OPERATION_INFO_MODIFY => '基本信息修改',
        self::OPERATION_SERVICE_OPEN_FAIL => '开通服务失败',
        self::OPERATION_COMPANY_CREATE => '创建商户',
        self::OPERATION_APP_CREATE => '创建应用' ,
        self::OPERATION_COPY_CONFIG => '拷贝联调配置到正式',
        self::OPERATION_AUTHTEST => '修改内测属性',
    );
    const OP_LOG_TABLE = "operation_log";
    private $_opLogTableDb;
    private $_appModel;
    /* 老OA库句柄 */
    private $_conn;
    public static function getConstantValueByName ($name, $default = 0)
    {
        return self::_getConstByName($name, '', $default, 'OaLogModel');
    }
    public function __construct ($logger = null)
    {
        if (is_null($logger)) {
            $logger = getOaModelLogger();
        }
        parent::__construct($logger);
        $dbConfig = Oa_Util_Config::getSingleDbConfig(OA_WEB_DB_CLUSTER_ID);
        $db = OpDbModel::getInstance($dbConfig, $logger);
        $this->_opLogTableDb = new OpTableModel($db, self::OP_LOG_TABLE, $logger);
        $this->_appModel = new OaAppModel(OaAppModel::APP_CONFIG_ENV_PRODUCTION, $logger);
       
    }
    /**
     * 获取动作类型 
     * @param int $opType 
     * 
     * @return array|string $opType不为null，返回操作名称；其它返回全部动作
     */
    public function getOPType ($opType = null)
    {
        if ($opType) {
            return self::$_opList[$opType];
        }
        return self::$_opList;
    }
    /**
     * 获取记录列表
     * @param array $where array(op_type=> 动作类型
     * app_id=> 产品ID 默认
     * company_id=> 商户ID
     * op_environment=>环境)
     * @param int $offset
     * @param int $count 
     * @param string $sort
     * @param array $otherWhere 附加条件
     * 
     * @return mixed
     */
    public function getOpLog ($where, $offset = 0, $count = null, $sort = null, $otherWhere=null)
    {        
        $sql = "SELECT * FROM " . self::OP_LOG_TABLE . getSqlCond($where, $offset, $count, $sort, 
            $otherWhere);
        $result = $this->_opLogTableDb->query($sql);
        if ($result === false) {
            $this->_logger->log("query failed");
            return false;
        }
        return $result;
    }
    /**
     * 获取记录条数
     * @param array $where array(op_type=> 动作类型
     * app_id=> 产品ID 默认
     * company_id=> 商户ID
     * op_environment=>环境)
     * @param array 附加条件 $otherWhere
     * 
     * @return array|boolean
     */
    public function getOpLogCount ($where, $otherWhere=null)
    {
        $sql = "SELECT COUNT(*) FROM " . self::OP_LOG_TABLE . getSqlCond($where, 0, 0, null, 
            $otherWhere);
        $result = $this->_opLogTableDb->query($sql, PDO::FETCH_NUM);
        if ($result === false) {
            $this->_logger->log("query failed");
            return false;
        }
        return (int) $result[0][0];
    }
    /**
     * 
     */
    private function createOAWebInc()
    {
        if(!$this->_conn){
            $dbConfig = Oa_Util_Config::getSingleDbConfig(OAII_OAWEB_DB_CLUSTER_ID);
            //$dbConfig = array('user'=>'oaweb', 'pass'=>'oaweb', 'host'=>'10.70.10.7', 'name'=>'tmptest', 'port'=>'1521');
            $_conn = oci_connect($dbConfig['user'], $dbConfig['pass'], 
            "{$dbConfig['host']}:{$dbConfig['port']}/{$dbConfig['name']}", 'AL32UTF8');
            if (! $_conn) {
                $e = oci_error($st);
                $this->_logger->log("[{$e['code']}] {$e['message']}: {$e['sqltext']}");
                return false;
            }
            $this->_conn = $_conn;
            
        }
       
    }
	/**
     * 获取记录列表
     * @param array $where array(OP_FLAG=> 动作类型 只有,1,2,3
     * OP_SERVICE=> 产品ID 默认
     * USER_ID => 用户ID
     * company_id=> 商户ID
     * op_environment=>环境)
     * @param int $offset
     * @param int $count 
     * @param string $sort
     * 
     * @return mixed array(USER_ID=>操作用户ID,CREATE_TIME=>添加时间,CONTENT=>内容,APPNAME=>应用名称,OP=>动作)
     */
    public function getOpLogHis ($fromDate, $toDate, $where, $offset = 0, $count = 10)
    {        
        $this->createOAWebInc();
        $table = "TB_OPERATION_LOG";
        $translate = array('app_id'=>'OP_SERVICE', 'company_id'=>'CONTENT', 'op_environment'=>'OP_ENVIRONMENT' );
        $sql = "SELECT * FROM 
        (SELECT ROWNUM RN, A.* FROM
	  	(SELECT USER_ID, CREATE_TIME, CONTENT, IP, LEVEL_ID, OP_FLAG, OP_SERVICE, OP_ENVIRONMENT  FROM ".$table."
		 WHERE TRUNC(CREATE_TIME) BETWEEN TO_DATE(:fromDate, 'yyyy-mm-dd hh24:mi:ss') 
        AND TO_DATE(:toDate, 'yyyy-mm-dd hh24:mi:ss') AND NOT(OP_SERVICE=-1) ";
        foreach($where as $k=>$val) {
            switch ($k) {
                case 'op_environment':
                    if ($val == self::APP_CONFIG_ENV_PRODUCTION) {
                        $sql .= "AND OP_ENVIRONMENT IN(2,3) ";
                    } else {
                        $sql .= "AND OP_ENVIRONMENT=1 ";
                    }
                    break;
                default:
                    if(is_array($val)){
                        $sql .= "AND {$k} IN (".join(",", $val).") ";
                    } else{
                        $sql .= "AND {$k} = '{$val}' ";    
                    }
            }
        }
        $sql.="ORDER BY CREATE_TIME DESC 
        ) A WHERE ROWNUM<= :end
        ) WHERE RN> :begin ";
        $st = oci_parse($this->_conn, $sql);
        oci_bind_by_name($st, ':fromDate', $fromDate);
        oci_bind_by_name($st, ':toDate', $toDate);
        oci_bind_by_name($st, ':begin', $offset);
        $end = $offset+$count;
        oci_bind_by_name($st, ':end', $end);
        if (! oci_execute($st)) {
            $e = oci_error($st);
            $this->_logger->log("[{$e['code']}] {$e['message']}: {$e['sqltext']}");
            return false;
        }
        $rows = array();
        if (oci_fetch_all($st, $rows, 0, - 1, OCI_FETCHSTATEMENT_BY_ROW + OCI_ASSOC) === false) {
            $e = oci_error($st);
            $this->_logger->log("[{$e['code']}] {$e['message']}: {$e['sqltext']}");
            return false;
        }
        
        $this->pasrseArr($rows);
        return $rows;
    }
    /**
     * 重构内容
     * @param array $arr
     * 
     * @return void
     */
    private function pasrseArr (&$arr)
    {
        if (! $arr) {
            return $arr;
        }
        $ids = array();
        foreach ($arr as $row) {
            $ids[$row['SERVICEID']] = 1;
        }
        $apps = $this->_appModel->getAppMulti(array_keys($ids));
        foreach ($arr as $k => $row) {
            if ($row['OP_SERVICE'] != - 1) {
                $arr[$k]['APPNAME'] = $apps[$row['OP_SERVICE']]['name'];
            } else {
                $arr[$k]['CONTENT'] = strtr($row['CONTENT'], 
                array(
                    $row['USER_ID'] . ":" => ""
                ));
            }
            $arr[$k]['OP'] = $row['OP_FLAG'] == self::OPERATION_DELETE ? "取消" : ($row['OP_FLAG'] == self::OPERATION_UPDATE ? "修改" : "插入");
        }
    }
    /**
     * 获取记录条数
     * @param array $where array(OP_FLAG=> 动作类型
     * OP_SERVICE=> 产品ID 默认
     * USER_ID => 用户ID
     * op_environment=>环境)
     * @param array 附加条件 $otherWhere
     * 
     * @return array|boolean
     */
    public function getOpLogHisCount ($fromDate, $toDate, $where)
    {
        $this->createOAWebInc();
        $fromDate = date("Y-m-d 00:00:00", strtotime($fromDate));
        $toDate = date("Y-m-d 23:59:59", strtotime($toDate));
        $table = "TB_OPERATION_LOG";
        $sql = "SELECT COUNT(*) FROM {$table} WHERE TRUNC(CREATE_TIME) BETWEEN TO_DATE(:fromDate, 'yyyy-mm-dd hh24:mi:ss') 
        AND TO_DATE(:toDate, 'yyyy-mm-dd hh24:mi:ss') AND NOT(OP_SERVICE=-1) ";
        foreach($where as $k=>$val)
        {
            switch($k)
            {
                case 'op_environment':
                    if($val==self::APP_CONFIG_ENV_PRODUCTION){
                        $sql .= "AND OP_ENVIRONMENT IN(2,3) ";       
                    }
                    else {
                        $sql .= "AND OP_ENVIRONMENT=1 "; 
                    }
                    break;
                default:
                    if(is_array($val)){
                        $sql .= "AND {$k} IN (".join(",", $val).") ";
                    } else{
                        $sql .= "AND {$k} = '{$val}' ";    
                    }
                    
            }            
            
        }
        $st = oci_parse($this->_conn, $sql);
        oci_bind_by_name($st, ':fromDate', $fromDate);
        oci_bind_by_name($st, ':toDate', $toDate);
        if (!oci_execute($st)) {
            $e = oci_error($st);
            $this->_logger->log("[{$e['code']}] {$e['message']}: {$e['sqltext']}");
            return false;
        }
        $row = oci_fetch_row($st);
        if ($row === false) {
            $e = oci_error($st);
            $this->_logger->log("[{$e['code']}] {$e['message']}: {$e['sqltext']}");
            return false;
        }
        return (int) $row[0];
    }
    /**
     * 创建应用
     * @param int $opType 动作类型
     * @param int $developer_id 开发者ID 
     * @param string $ip 操作时IP地址
     * @param string $content 内容
     * @param int $appId 应用ID
     * @param array $row 附加信息（create_time,company_id ）
     * @param int $env 环境 1联调2正式
     * 
     * @return int|boolean
     */
    public function createOpLog ($opType, $developerId, $ip, $content, $appId = -1, $row = array(), $env = 1)
    {
        // @TODO 检查是否具备写入日志的权限
        if (! isset(self::$_opList[$opType])) {
            $this->_logger->log("Invalid Paramter op_type");
            return false;
        }
        $row = array_merge(array(
            'op_type' => $opType, 
            'developer_id' => $developerId, 
            'content' => escapeRawInputValue($content), 
            'ip' => $ip, 
            'app_id' => $appId, 
            'op_environment' => $env
        ), $row);
        if (! isset($row['create_time'])) {
            $row['create_time'] = date('Y-m-d H:i:s');
        }
        $logId = $this->_opLogTableDb->insert($row);
        return $logId;
    }
}
?>
